-- $Id: DKPTable.lua,v 1.52 2008/08/07 12:20:14 dmitry Exp $

local DKPT_ENABLE_CHATHOOK=true
DKPT_ENABLE_CHATHOOK=false


local DEBUG = 9

local OriginalChatFrame_OnEvent;
local OriginalUnitPopup_OnClick;

DKPT_ADDON_NAME = "DKP Table"
DKPT_ADDON_VERSION_CVS = "$Revision: 1.52 $"
DKPT_ADDON_VERSION = string.gsub(DKPT_ADDON_VERSION_CVS,"%D+(%d+%.%d+)%D+","%1");
DKPT_TITLE = DKPT_ADDON_NAME.." "..DKPT_ADDON_VERSION
DKPT_LOADED = false

local DKPT_POSITIVE_COLOR = "|c003FFF3F"
local DKPT_NEGATIVE_COLOR = "|c00FF3F3F"
local DKPT_ZERO_COLOR     = "|c00AFAFAF"

local SORT_FIELD		= "current"
local SORT_ORDER		= false
local IS_FILTER			= false
local FILTER			= ""
local DKPT_ChatFrame	= nil;

local SHOW_NOTINRAID = true
local DKPT_default_ChatLines=10;

local RaidList = ""
local RaidRanks = {}
local RaidClasses = {}
local Classes = {}
DKP_table_sorted={}
DKPT_Selected_Member=0;
DKPT_Selected_InTable=0;

local LOG_COLORS = {  
	"|c00FF0000", "|c00FFFF00", "|c00FFFF00", 
	"|c00FFFF00", "|c00FFFF00", "|c00FFFF00", 
	"|c00FFFF00", "|c00FFFFFF", "|c00C0C0C0" 
};
local LOG_TIME_COLOR = "|c0090FF90";

Classes[1] = DKPT_priest;
Classes[2] = DKPT_mage;
Classes[3] = DKPT_warlock;
Classes[4] = DKPT_druid;
Classes[5] = DKPT_hunter;
Classes[6] = DKPT_rogue;
Classes[7] = DKPT_warrior;
Classes[8] = DKPT_paladin;   
Classes[9] = DKPT_shaman;   

Classes[DKPT_priest]	= { color="|c00FFFFFF", id=1, left=0.50, right=0.75, bottom=0.25, top=0.50 };
Classes[DKPT_mage] 		= { color="|c0068CCEF", id=2, left=0.25, right=0.50, bottom=0.00, top=0.25 };
Classes[DKPT_warlock] 	= { color="|c009382c9", id=3, left=0.75, right=1.00, bottom=0.25, top=0.50 };
Classes[DKPT_druid] 	= { color="|c00FF7C0A", id=4, left=0.75, right=1.00, bottom=0.00, top=0.25 };
Classes[DKPT_hunter] 	= { color="|c00AAD372", id=5, left=0.00, right=0.25, bottom=0.25, top=0.50 };
Classes[DKPT_rogue] 	= { color="|c00FFF468", id=6, left=0.50, right=0.75, bottom=0.00, top=0.25 };
Classes[DKPT_warrior]	= { color="|c00C69B6D", id=7, left=0.00, right=0.25, bottom=0.00, top=0.25 };
Classes[DKPT_paladin]	= { color="|c00F48CBA", id=8, left=0.00, right=0.25, bottom=0.50, top=0.75 };
Classes[DKPT_shaman]	= { color="|c0024FCDA", id=9, left=0.25, right=0.50, bottom=0.25, top=0.50 };

local ShowClass = {}
ShowClass[DKPT_priest]  = true
ShowClass[DKPT_mage]    = true
ShowClass[DKPT_warlock] = true
ShowClass[DKPT_druid]   = true
ShowClass[DKPT_hunter]  = true
ShowClass[DKPT_rogue]   = true
ShowClass[DKPT_warrior] = true
ShowClass[DKPT_shaman]  = true
ShowClass[DKPT_paladin] = true

function DKPT_OnLoad()
	local i;
	SlashCmdList["DKPTable"] = DKPT_SlashCommandHandler
	SLASH_DKPTable1 = "/dkptable"
	SLASH_DKPTable2 = "/dkpt"
	SLASH_DKPTable3 = "/dkp"

	tinsert(UISpecialFrames,"DKPT_Main_Frame"); 
	this:RegisterEvent("PLAYER_ENTERING_WORLD");
	this:RegisterEvent("RAID_ROSTER_UPDATE");
	this:RegisterEvent("VARIABLES_LOADED");

	OriginalUnitPopup_OnClick=UnitPopup_OnClick;
	if DKPT_ENABLE_CHATHOOK then
		OriginalChatFrame_OnEvent	= ChatFrame_OnEvent;
		ChatFrame_OnEvent			= DKPT_ChatFrame_OnEvent;
		DKPT_DBG(9,"Chathook enabled.");
	else
		DKPT_AutoanswerFrame:Hide();
		DKPT_AutoAnswerTab:Hide();
		DKPT_DBG(9,"Chathook disabled.");
	end

--	DKPT_SetFaction();
	DKP_Members = 0
	DKP_table_members = 0
	if DKP_tables_count>0 then
		SetDKPTable(1);
	end
	DKPT_EnumerateRaid();

	getglobal("DKPTTitle_CurrentArrow"):SetTexCoord(0,0.5625,1,0.1);
	DKPT_Hide()
	DKPT_DBG(8,DKPT_ADDON_NAME," ",DKPT_ADDON_VERSION," loaded.");
	DKPT_DBG(9,"Locale=",GetLocale());
	DEFAULT_CHAT_FRAME:AddMessage(DKPT_ADDON_NAME.." "..DKPT_ADDON_VERSION.." loaded. "..DKP_table_members.." members in database.",1,1,1,1,1)
end

function DKPTScrollFrame_Update()
	local line;
	local class;
	local offset;
	if not DKPT_LOADED then return end;
	FauxScrollFrame_Update(DKPTScrollFrame,DKP_table_members,15,24);
--	DKPT_DBG(9,"Set DKP_Members=",DKP_Members);
	line=1
	offset=FauxScrollFrame_GetOffset(DKPTScrollFrame)+1
	while line<=15 do
		if offset<=DKP_table_members then
			class=DKP_table[DKP_table_sorted[offset]].class;
			nick=DKP_table[DKP_table_sorted[offset]].nick;
			if (ShowClass[class] and (SHOW_NOTINRAID or isKeyword(RaidList,DKP_table[DKP_table_sorted[offset]].nick)~=nil)) then
				if not IS_FILTER or (IS_FILTER and isKeyword(FILTER,nick)) then
					if(DKP_table_sorted[offset]==DKPT_Selected_Member) then
						getglobal("DKPTLine"..line):Disable();
					else
						getglobal("DKPTLine"..line):Enable();
					end
					getglobal("DKPTLine"..line.."_Num"):SetText(DKP_table_sorted[offset]);
					getglobal("DKPTLine"..line.."_TNum"):SetText(offset);
					getglobal("DKPTLine"..line.."_Class"):SetText(Classes[class].color..class);
					getglobal("DKPTLine"..line.."_Rank"):SetText(DKP_table[DKP_table_sorted[offset]].rank);
					getglobal("DKPTLine"..line.."_Nick"):SetText(Classes[class].color..nick);
					getglobal("DKPTLine"..line.."_Spent"):SetText(Color_Value_Reverse(string.format(DKPT_SV.SpentFormat,DKP_table[DKP_table_sorted[offset]].spent)));
					getglobal("DKPTLine"..line.."_Current"):SetText(Color_Value(string.format(DKPT_SV.CurrentFormat,DKP_table[DKP_table_sorted[offset]].current)));
					getglobal("DKPTLine"..line.."_ClassIcon"):SetTexCoord(Classes[class].right,Classes[class].left,Classes[class].bottom,Classes[class].top);
					getglobal("DKPTLine"..line):Show();
					line=line+1
				end
			end
		else
			getglobal("DKPTLine"..line):Hide();
			line=line+1
		end
		offset=offset+1
	end
end

function DKPT_Hide()
   HideUIPanel(DKPT_Main_Frame);
end

function DKPT_Toggle()
   if( DKPT_Main_Frame:IsVisible() ) then
      DKPT_Hide();
   else
      DKPT_Show();
   end
end

function DKPT_Show()
	DKPT_EnumerateMembers();
	DKPTScrollFrame_Update();
	ShowUIPanel(DKPT_Main_Frame);
end

function DKPT_SlashCommandHandler(msg)
    if msg~="" then
		DKPT_DBG(9,"set filter=",msg);
		IS_FILTER=true;
		DKPT_SetFilter(msg);
		getglobal("DKPT_FilterEdit"):SetText(msg);
		getglobal("DKPT_FilterCheck"):SetChecked(1);
		if not DKPT_Main_Frame:IsVisible() then
			DKPT_Show();
		end
	else
		DKPT_Toggle();
	end
end

function Color_Value(value)
	local vcolor;
	if(not value) then value=0; end
	if tonumber(value)>0 then
		vcolor = DKPT_POSITIVE_COLOR
	elseif tonumber(value)<0 then
		vcolor = DKPT_NEGATIVE_COLOR
	else 
		vcolor = DKPT_ZERO_COLOR
	end
	return vcolor..value
end

function Color_Value_Reverse(value)
	local vcolor;
	if(not value) then value=0; end
	if tonumber(value)>0 then
		vcolor = DKPT_NEGATIVE_COLOR
	elseif tonumber(value)<0 then
		vcolor = DKPT_POSITIVE_COLOR
	else 
		vcolor = DKPT_ZERO_COLOR
	end
	return vcolor..value
end

function DKPT_SetShow(class,checked)
	ShowClass[class]=checked
	DKPT_EnumerateMembers();
	DKPTScrollFrame_Update();
end

function DKPT_ShowNotInRaid_OnClick(checked)
	SHOW_NOTINRAID=checked
	DKPT_EnumerateRaid();
	DKPT_EnumerateMembers();
	DKPTScrollFrame_Update();
end

function DKPT_TablesList_OnClick()
	SetDKPTable(this:GetID());
	DKPT_SV.SelectedTable=this:GetID();
	DKPT_DBG(8,DKP_table_title," table loaded.");
	DKPT_EnumerateMembers();
	DKPTScrollFrame_Update();
	UIDropDownMenu_SetSelectedID(DKPT_TablesList, this:GetID());
end

function DKPT_TablesList_Init()
	local info = {};
	local i=1;
	if DKPT_LOADED then
		while i<=DKP_tables_count do
			info.text = DKP_tables[i].title
			info.func = DKPT_TablesList_OnClick
			info.value = i
			info.checked = (i == DKPT_SV.SelectedTable)
			UIDropDownMenu_AddButton(info)
			i=i+1
			DKPT_DBG(9,'Adding dkp table to droplist: ',info.text);
		end
	end
end

function SetDKPTable(id)
	local i,v;
	DKPT_DBG(9,"SetDKPTable id=",id);
	if(DKP_table_id and DKP_table_id~=id) then
		DKP_tables[DKP_table_id]=DKP_table;
	end
	DKP_table=nil;
	DKP_table={}
	DKP_table_id=id;
	DKP_table_title=DKP_tables[id].title;
	DKP_table_url=DKP_tables[id].url;
	DKP_table_members=DKP_tables[id].members;
	DKPT_DBG(9,"SetDKPTable table_members=",DKP_tables[id].members);
	DKP_table=DKP_tables[id];
	DKP_table_sorted={};
	for i,v in pairs(DKP_table) do DKP_table_sorted[i]=i; end
	table.sort(DKP_table_sorted,
		function(a,b)
			if SORT_ORDER then
				return DKP_table[a][SORT_FIELD]<DKP_table[b][SORT_FIELD]
			else
				return DKP_table[a][SORT_FIELD]>DKP_table[b][SORT_FIELD]
			end
		end
	)
	DKP_Members=DKP_table_members
end

function DKPT_ChangeSort(field)
	local tab={ 
		["class"]="Class", 
		["nick"]="Nick", 
		["rank"]="Rank",
		["spent"]="Spent", 
		["current"]="Current"
	};
	local top;
	local bottom;
	local old_sort_field=SORT_FIELD;
	if field==SORT_FIELD then
		SORT_ORDER=not SORT_ORDER
		if SORT_ORDER then 
			top=0; 
			bottom=1;
		else 
			top=1; 
			bottom=0.1;
		end
	else
		SORT_FIELD=field
		SORT_ORDER=true
		top=0; 
		bottom=1;
	end
	table.sort(DKP_table_sorted,
		function(a,b)
			local aa=DKP_table[a][SORT_FIELD];
			local bb=DKP_table[b][SORT_FIELD];
			if (field=='current' or field=='spent') then
				aa=dNum(aa);
				bb=dNum(bb);
			else
			    aa=dStr(aa);
			    bb=dStr(bb);
			end
			if SORT_ORDER then
				return aa<bb
			else
				return aa>bb
			end
		end
	)
	getglobal("DKPTTitle_"..tab[old_sort_field].."Arrow"):SetTexCoord(0,0,0,0);
	getglobal("DKPTTitle_"..tab[SORT_FIELD].."Arrow"):SetTexCoord(0,0.5625,top,bottom);
	DKPTScrollFrame_Update()
end

--[[
function DKPT_SetFaction()
	local faction = UnitFactionGroup("PLAYER");
	if not faction then return end
	DKPT_DBG(8,"Player's faction - ",faction);
	if faction=="Horde" then
		Classes[8]=DKPT_shaman
		DKPT_shadin=DKPT_shaman
		DKPT_Shadins=DKPT_Shamans
		getglobal("ShowShadinButtonLabel"):SetText(DKPT_Shamans);
	else
		Classes[8]=DKPT_paladin
		DKPT_shadin=DKPT_paladin
		DKPT_Shadins=DKPT_Paladins
		getglobal("ShowShadinButtonLabel"):SetText(DKPT_Paladins);
	end
end
]]--

function DKPT_EnumerateRaid()
	local name,rank,class;
	local dkplua="";
	local dkpadded=nil;
	DKPT_DBG(9,GetNumRaidMembers()," members in raid.");
	if GetNumRaidMembers()>0 then
		i=1;
		while i<=DKP_table_members do
			dkplua=dkplua.." "..string.lower(DKP_table[i].nick).." ";
			i=i+1;
		end
		i=1;
		RaidList="";
		RaidRanks={};
		while i<=40 do
			name,rank,_,_,class=GetRaidRosterInfo(i);
			if name then 
				RaidList=RaidList.." "..name.." ";
				RaidRanks[name]=rank;
				RaidClasses[name]=class;
				if string.find(dkplua," "..string.lower(name).." ",1,true)==nil then
					DKP_table_members=DKP_table_members+1;
					DKP_table.members=DKP_table_members;
					local class=UnitClass("raid"..i);
					DKP_table[DKP_table_members]={};
					DKP_table[DKP_table_members].nick=name;
					DKP_table[DKP_table_members].rank=DKPT_txt_NotInTable;
					DKP_table[DKP_table_members].class=string.lower(class);
					DKP_table[DKP_table_members].current=0;
					DKP_table[DKP_table_members].spent=0;
					DKPT_DBG(8,"raid member ",name," absent in dkp.lua. Added with 0 value at position ",DKP_table_members);
					dkpadded=1;
				end
			end
			i=i+1
		end
		if dkpadded then 
			DKP_tables[DKP_table_id]=DKP_table;
			SetDKPTable(DKP_table_id); 
		end
--		DKPT_DBG(9,"In Raid. Members: ",RaidList);
	else
		DKPT_DBG(9,"Not in raid.");
	end
end

function DKPTPrintDKP_OnCLick()
	local i=1;
	local j=1;
	local class;
	local channel;
	local chatnumber;
	local spent;

	if ChatFrameEditBox:IsVisible() then
		channel = ChatFrameEditBox:GetAttribute("chatType");
		DKPT_DBG(9,"cannel=",channel,"; chatnumber=",chatnumber);
		if channel=="WHISPER" then
			chatnumber = ChatFrameEditBox:GetAttribute("tellTarget");
		elseif channel=="CHANNEL" then
			chatnumber = ChatFrameEditBox:GetAttribute("channelTarget");
		end
		if DKPT_SV.PrintTableName then
			SendChatMessage(DKPT_SV.ChatPrefix..string.format(DKPT_txt_PrintTNPref,DKP_table_title),channel,nil,chatnumber);
		end
		if DKPT_SV.PrintTimestamp then
			SendChatMessage(DKPT_SV.ChatPrefix..string.format(DKPT_txt_PrintTSPref,DKP_tables_timestamp),channel,nil,chatnumber);
		end
		while i<=DKP_table_members do
			class=DKP_table[DKP_table_sorted[i]].class
			if (ShowClass[class] and (SHOW_NOTINRAID or string.find(RaidList,DKP_table[DKP_table_sorted[i]].nick)~=nil)) then
   				if not IS_FILTER or (IS_FILTER and string.find(FILTER,string.lower(DKP_table[DKP_table_sorted[i]].nick).." ",1,true)) then
   					if(DKP_table[DKP_table_sorted[i]].spent==0) then
   						spent="";
   					else
   						spent=" "..string.format(DKPT_SV.ChatDKPspent,(-DKP_table[DKP_table_sorted[i]].spent));
   					end
        			SendChatMessage(DKPT_SV.ChatPrefix..string.format(DKPT_SV.ChatDKP,j,DKP_table[DKP_table_sorted[i]].nick,DKP_table[DKP_table_sorted[i]].current)..spent,channel,nil,chatnumber);
					j=j+1
					if(j>DKPT_SV.ChatLines) then break; end
		    	end
			end
			i=i+1
		end
	else
		DEFAULT_CHAT_FRAME:AddMessage(DKPT_txt_OpenChat,1,1,1,1,1)
	end
end

function DKPT_EnumerateMembers()
	local i=1;
	local vism=0;
	local class;
	
	if DKPT_LOADED then 
--		DKPT_DBG(9,"DKPT_LOADED=",DKPT_LOADED,"; DKP_table_members=",DKP_table_members);
		DKP_Members=DKP_table_members;
		while i<=DKP_table_members do
			class=DKP_table[DKP_table_sorted[i]].class
			RaidClasses[DKP_table[DKP_table_sorted[i]].nick]=class;
			if (ShowClass[class] and (SHOW_NOTINRAID or string.find(RaidList,DKP_table[DKP_table_sorted[i]].nick)~=nil)) then
				if not IS_FILTER or (IS_FILTER and string.find(FILTER,string.lower(DKP_table[DKP_table_sorted[i]].nick).." ",1,true)) then
					vism=vism+1
		    	end
			end
			i=i+1
		end
--		DKPT_DBG(9,"Set vism=",vism);
		DKP_Members=vism;
	end
end


function DKPT_SetFilterCheck(checked)
	IS_FILTER=checked;
	if IS_FILTER then
		DKPT_SetFilter(getglobal("DKPT_FilterEdit"):GetText());
		DKPT_DBG(9,"Filter on.");
	else
		DKPT_DBG(9,"Filter off.");
	end
	DKPT_EnumerateMembers();
	DKPTScrollFrame_Update();
end

function DKPT_SetFilter(text)
--[[	local i=1;
	local match;
    FILTER = {}
	if text then
	    text=string.gsub(text,"%*",".+");
		DKPT_DBG(9,"Filter=",text);
		for match in string.gmatch(text,"%S+") do
			FILTER[i]=match;
			DKPT_DBG(9,"  ",i," : ",match);
			i=i+1;	
		end
	else
		FILTER = {}
	end
]]--
	FILTER=string.lower(text).." ";
	DKPT_DBG(9,"Filter=",text);
	if IS_FILTER then
		DKPT_EnumerateMembers();
		DKPTScrollFrame_Update();
	end
end

function DKPT_Member_OnClick()
	local class=getglobal(this:GetName().."_Class"):GetText();
	local nick=getglobal(this:GetName().."_Nick"):GetText();
	local spent=getglobal(this:GetName().."_Spent"):GetText();
	local current=getglobal(this:GetName().."_Current"):GetText();

	DKPT_Selected_Member=tonumber(getglobal(this:GetName().."_Num"):GetText());
	DKPT_Selected_InTable=tonumber(getglobal(this:GetName().."_TNum"):GetText());
	DKPT_DBG(9,"table select: ",DKPT_Selected_Member,", ",DKPT_Selected_InTable,", ",DKP_table[DKPT_Selected_Member].nick);
	DKPTScrollFrame_Update();
	DKPT_Select_Nick:SetText(class.."  "..nick);
	DKPT_Select_Spent:SetText(spent);
	DKPT_Select_Current:SetText(current);
	DKPT_Select:Show();
end

function DKPT_Tab_OnCLick()
	DKPT_Frame:Hide();
	DKPT_TableTab:SetFrameLevel(DKPT_Main_Frame:GetFrameLevel()-1);

	DKPT_LogFrame:Hide();
	DKPT_LogTab:SetFrameLevel(DKPT_Main_Frame:GetFrameLevel()-1);

	DKPT_AutoanswerFrame:Hide();
	DKPT_AutoAnswerTab:SetFrameLevel(DKPT_Main_Frame:GetFrameLevel()-1);

	DKPT_OptionsFrame:Hide();
	DKPT_OptionsTab:SetFrameLevel(DKPT_Main_Frame:GetFrameLevel()-1);

	if this:GetName()=="DKPT_TableTab" then
		DKPT_Frame:Show();
	elseif this:GetName()=="DKPT_LogTab" then
		DKPT_LogFrame:Show();
	elseif this:GetName()=="DKPT_OptionsTab" then
		DKPT_OptionsFrame:Show();
	elseif this:GetName()=="DKPT_AutoAnswerTab" then
		DKPT_AutoanswerFrame:Show();
	end
	this:SetFrameLevel(DKPT_Main_Frame:GetFrameLevel()+1);
end

function DKPT_GetTime()
	local hour, minute = GetGameTime();
	local t = hour;
	if( hour < 10 ) then t = "0"..t; end
	t = t..":";
	if( minute < 10 ) then t = t.."0"; end
	t = t..minute;
	return t;
end

function DKPT_OnEvent(event)
	local i,j,k,iv;
	DKPT_DBG(9,"event: ",event);
	if event=="PLAYER_ENTERING_WORLD" then
--		DKPT_SetFaction();
		DKPT_EnumerateRaid();
	elseif event=="RAID_ROSTER_UPDATE" then
		DKPT_EnumerateMembers();
		DKPT_EnumerateRaid();
		DKPTScrollFrame_Update()
	elseif event=="VARIABLES_LOADED" then
		if DKP_tables_count>0 then
			SetDKPTable(1);
		end
		if(not DKPT_SV) then
			DKPT_DBG(8,"Variables loaded. First run. ",DKPT_ADDON_VERSION_CVS);
			DKPT_SV={};
			DKPT_SV.run=1;
			DKPT_SV.revision=DKPT_ADDON_VERSION_CVS;
			DKPT_SV.tables=DKP_tables;
			DKPT_SV.tablescount=DKP_tables_count;
			DKPT_SV.timestamp=DKP_tables_timestamp;
		else
			DKPT_SV.run=DKPT_SV.run+1;
			DKPT_DBG(9,"Variables loaded. Running ",DKPT_SV.run," time.");
			DKPT_DBG(9,"Saved DKP tables found: ",DKPT_SV.tablescount);
			if(DKPT_SV.tablescount==DKP_tables_count and DKPT_SV.tablescount and 
					DKPT_SV.timestamp==DKP_tables_timestamp and DKPT_SV.timestamp and 
					DKPT_SV.revision==DKPT_ADDON_VERSION_CVS) then
				DKPT_DBG(8,"Saved spent data found. Restore previous session.");
				DKPT_DBG(9,"timestamp=",DKPT_SV.timestamp);
				DKP_tables=DKPT_SV.tables;
				if DKP_tables_count>0 then
					SetDKPTable(1);
					DKPT_EnumerateMembers();
					DKPTScrollFrame_Update();
				end
			else
				DKPT_DBG(8,"Saved data out of date or was corrupted. Initializing saved variables.");
				DKP_run=DKPT_SV.run;
				DKPT_SV.run=DKPT_SV.run+1;
				DKPT_SV.revision=DKPT_ADDON_VERSION_CVS;
				DKPT_SV.tables=DKP_tables;
				DKPT_SV.tablescount=DKP_tables_count;
				DKPT_SV.timestamp=DKP_tables_timestamp;
			end
		end
		if DKPT_SV.HookPopup then
			DKPT_DBG(9,"Set hook for friends popup menu.");
			DKPT_HookPopup(1);
		end
		if(DKPT_SV.MMArc==nil or DKPT_SV.MMRadius==nil or DKPT_SV.revision~=DKPT_ADDON_VERSION_CVS) then
			DKPT_DBG(9,"minimap icon: no saved data, setting to default");
			DKPT_MinimapIcon_Init();
		end
		DKPT_MinimapIcon_SetWidgets();
		if(DKPT_SV.ChatLines==nil or DKPT_SV.revision~=DKPT_ADDON_VERSION_CVS) then 
			DKPT_ChatOpt_Init();
		elseif(type(DKPT_SV.ChatLines)~="number") then 
			DKPT_ChatOpt_Init();
		elseif(DKPT_SV.ChatLines<=0) then 
			DKPT_ChatOpt_Init(); 
		end
		DKPT_ChatOpt_SetWidgets();
		if(DKPT_SV.AASAllow==nil or DKPT_SV.revision~=DKPT_ADDON_VERSION_CVS) then DKPT_Autoanswer_Init(); end
		DKPT_Autoanswer_SetWidgets();
		if not DKPT_SV.SelectedTable then 
			DKPT_SV.SelectedTable=1; 
		end
		if (DKPT_SV.SelectedTable<1 or DKPT_SV.SelectedTable>DKPT_SV.tablescount) then 
			DKPT_SV.SelectedTable=1;
		end
		SetDKPTable(DKPT_SV.SelectedTable);
		DKPT_TablesList_Init();
		DKPT_DBG(9,"Set table title to: ",DKP_table_title);
		UIDropDownMenu_Initialize(DKPT_TablesList,DKPT_TablesList_Init);
		UIDropDownMenu_SetSelectedID(DKPT_TablesList,DKPT_SV.SelectedTable);
		DKPT_TablesListText:SetText(DKP_table_title);
	else
		DKPT_DBG(1,"unhandled event: ",event)
	end
	DKPT_LOADED = true;
	DKPT_EnumerateMembers();
	DKPTScrollFrame_Update();
end

function DKPT_ResetOptions_OnClick()
	DKPT_MinimapIcon_Init();
	DKPT_MinimapIcon_SetWidgets();
	DKPT_ChatOpt_Init();
	DKPT_ChatOpt_SetWidgets();
	DKPT_DBG(8,"Chat and minimap settings were set to defaults");
end

function DKPT_MinimapIcon_Init()
	DKPT_SV.MMShow=1;
	DKPT_SV.MMArc=23;
	DKPT_SV.MMRadius=81;
end

function DKPT_MinimapIcon_SetWidgets()
	DKPT_ShowMM:SetChecked(DKPT_SV.MMShow);
	DKPT_MMArcSlider:SetValue(DKPT_SV.MMArc);
	DKPT_MMRadiusSlider:SetValue(DKPT_SV.MMRadius);
	if(DKPT_SV.MMShow==1) then
		DKPT_UpdateMinimapIcon();
	else
	    DKPT_MinimapIcon:Hide();
	end
end

function DKPT_ChatOpt_Init()
	DKPT_SV.ChatPrefix=DKPT_default_ChatPrefix;
	DKPT_SV.ChatLines=DKPT_default_ChatLines;
	DKPT_SV.SpentFormat=DKPT_default_SpentFormat;
	DKPT_SV.CurrentFormat=DKPT_default_CurrentFormat;
	DKPT_SV.ChatDKP=DKPT_default_ChatDKP;
	DKPT_SV.ChatDKPspent=DKPT_default_ChatDKPspent;
	DKPT_SV.PrintTimestamp=1;
	DKPT_SV.PrintTableName=1;
	DKPT_SV.HookPopup=1;
end

function DKPT_ChatOpt_SetWidgets()
	local p="DKPT_OptionsFrameChatOptions_";
	DKPT_SV.ChatLines=dNum(DKPT_SV.ChatLines);
	getglobal(p.."ChatPrefix_Editbox"):SetText(dStr(DKPT_SV.ChatPrefix));
	getglobal(p.."ChatLines_Editbox"):SetText(DKPT_SV.ChatLines);
	getglobal(p.."SpentFormat_Editbox"):SetText(dStr(DKPT_SV.SpentFormat));
	getglobal(p.."CurrentFormat_Editbox"):SetText(dStr(DKPT_SV.CurrentFormat));
	getglobal(p.."ChatDKP_Editbox"):SetText(dStr(DKPT_SV.ChatDKP));
	getglobal(p.."ChatDKPspent_Editbox"):SetText(dStr(DKPT_SV.ChatDKPspent));
	getglobal(p.."PrintTimestamp"):SetChecked(dNum(DKPT_SV.PrintTimestamp));
	getglobal(p.."PrintTableName"):SetChecked(dNum(DKPT_SV.PrintTableName));
	getglobal(p.."HookPopup"):SetChecked(dNum(DKPT_SV.HookPopup));
	getglobal(p.."FilterOutAA"):SetChecked(dNum(DKPT_SV.FilterOutAA));
end

function DKPT_ResetAutoanswer_OnClick()
	DKPT_Autoanswer_Init();
	DKPT_Autoanswer_SetWidgets();
	DKPT_DBG(8,"Autoanswering settings were set to defaults");
end

function DKPT_Autoanswer_Init()
	DKPT_SV.AASAllow=1;
	DKPT_SV.AASPromoted=0;
	DKPT_SV.AASAny=0;
	DKPT_SV.AAKeywords=DKPT_default_AAKeywords;
	DKPT_SV.AAMydkp=DKPT_default_AAMydkp;
	DKPT_SV.AATopten=DKPT_default_AATopten;
	DKPT_SV.AANicks=DKPT_default_AANicks;
	DKPT_SV.AAMyClass=DKPT_default_AAMyClass;
end

function DKPT_Autoanswer_SetWidgets()
	local p="DKPT_AutoanswerFrame_";
	DKPT_HookChatFrame(DKPT_SV.AASAllow);
	getglobal(p.."AASAllow"):SetChecked(dNum(DKPT_SV.AASAllow));
	getglobal(p.."AASPromoted"):SetChecked(dNum(DKPT_SV.AASPromoted));
	getglobal(p.."AASAny"):SetChecked(dNum(DKPT_SV.AASAny));
	getglobal(p.."AAOptions_AAKeywords_Editbox"):SetText(dStr(DKPT_SV.AAKeywords));
	getglobal(p.."AAOptions_AAMydkp_Editbox"):SetText(dStr(DKPT_SV.AAMydkp));
	getglobal(p.."AAOptions_AATopten_Editbox"):SetText(dStr(DKPT_SV.AATopten));
	getglobal(p.."AAOptions_AANicks_Editbox"):SetText(dStr(DKPT_SV.AANicks));
	getglobal(p.."AAOptions_AAMyClass_Editbox"):SetText(dStr(DKPT_SV.AAMyClass));
end

function DKPT_HookPopup(state)
--[[    if state then
		UnitPopupButtons["DKPFILTER"]	= { text = DKPT_txt_AddToDKPFilter, dist = 0 };
		table.insert(UnitPopupMenus["FRIEND"],1,"DKPFILTER");
		UnitPopup_OnClick=DKPT_UnitPopup_OnClick;
	else
		if(UnitPopupMenus["FRIEND"][1]=="DKPFILTER") then
			table.remove(UnitPopupMenus["FRIEND"],1);
			UnitPopupButtons["DKPFILTER"]=nil;
			UnitPopup_OnClick=OriginalUnitPopup_OnClick;
		end
	end ]]--
end

function DKPT_HookChatFrame(state)
    if state then
		this:RegisterEvent("CHAT_MSG_WISPER");
		this:RegisterEvent("CHAT_MSG_WISPER_INFORM");
	else
		this:UnregisterEvent("CHAT_MSG_WISPER");
		this:UnregisterEvent("CHAT_MSG_WISPER_INFORM");
	end
end

function DKPT_UpdateSpent_OnClick()
	local newspent=dNum(DKPT_Select_Spent:GetText());
	local newcurrent=DKP_table[DKPT_Selected_Member].current+DKP_table[DKPT_Selected_Member].spent-newspent;
    DKP_table[DKPT_Selected_Member].current=newcurrent;
    DKP_table[DKPT_Selected_Member].spent=newspent;
    DKP_tables[DKP_table_id][DKPT_Selected_Member].current=newcurrent;
    DKP_tables[DKP_table_id][DKPT_Selected_Member].spent=newspent;
    DKP_tables[DKP_table_id].title=DKP_table_title;
    DKP_tables[DKP_table_id].url=DKP_table_url;
    DKP_tables[DKP_table_id].members=DKP_table_members;
    DKPT_DBG(8,DKPT_Select_Nick:GetText()," for now spent ",newspent,"DKP, ",newcurrent,"DKP left.");
	table.sort(DKP_table_sorted,
		function(a,b)
			local aa=DKP_table[a][SORT_FIELD];
			local bb=DKP_table[b][SORT_FIELD];
			if SORT_ORDER then
				return aa<bb
			else
				return aa>bb
			end
		end
	)
	DKPT_Selected_Member=0;
	DKPT_Selected_InTable=0;
	DKPT_Select:Hide();
	DKPTScrollFrame_Update();
end

function strlow(str)
	if str then return string.lower(str); end
	return "";
end

function DKPT_ChatFrame_OnEvent(event)
	if not DKPT_SV.AASAllow then
		OriginalChatFrame_OnEvent(event);
		return 1;
	end 
	local text=arg1;
	local nick=arg2;
	local w,q1,q2,q3,i,v,answered;
	local found=false;
	local query={};
	local chkFilter=function()
			if not DKPT_SV.FilterOutAA then 
				OriginalChatFrame_OnEvent(event);
			end
		  end
	if (event=="CHAT_MSG_WHISPER") then
		if not DKPT_ChatFrame then DKPT_ChatFrame=this:GetName(); end
		if DKPT_ChatFrame==this:GetName() then
			DKPT_DBG(9,"whisper from ",nick," : ",text);
		end
		_,_,q1,q2,q3=string.find(strlow(text),"^(%S+)%s*(%S*)%s*(.*)$")
		if isKeyword(DKPT_SV.AAKeywords,q1) then
			if DKPT_ChatFrame~=this:GetName() then
				chkFilter(); 
				return 1; 
			end
			if not DKPT_SV.AASAllow then
				DKPT_DBG(8,"AA is turned off. Blocking query from ",nick);
				chkFilter(); 
				return 1;
			end
			if (DKPT_SV.AASPromoted~=1) then
				if (GetNumRaidMembers()==0) then
					DKPT_DBG(8,"Not in raid. . Blocking query from ",nick);
					chkFilter(); 
					return 1;
				elseif (not isRank(nick,1)) then
					DKPT_DBG(8,"Does not have promote or not a raid member. Blocking query from ",nick);
					chkFilter(); 
					return 1;
				end
			end
			if (DKPT_SV.AASAny~=1) then
				if (not isRank(nick,0)) then
					DKPT_DBG(8,"Not a raid member. Blocking query from ",nick);
					chkFilter(); 
					return 1;
				end
			end
		    DKPT_DBG(9,"Request from ",nick," is allowed.");
		    answered=0;
			if isKeyword(DKPT_SV.AAMydkp,q2) then
				DKPT_DBG(8,nick," wants his/her dkp...");
				DKPT_WhisperPrefix(nick);
				for i,v in pairs(DKP_table) do
				    if (type(v)=="table") then
						if (v.nick==nick) then
							SendChatMessage(DKPT_SV.ChatPrefix..string.format(DKPT_SV.ChatDKP,1,nick,v.current),"WHISPER",nil,nick);
							found=true;
							break;
						end
					end
				end
				if not found then SendChatMessage(DKPT_SV.ChatPrefix..string.format(DKPT_SV.ChatDKP,1,nick,0).." "..DKPT_txt_NotFoundInTable,"WHISPER",nil,nick); end
				answered=1;
			end
			if isKeyword(DKPT_SV.AATopten,q2) then
				DKPT_DBG(8,nick," wants top10 of dkp...");
				DKPT_WhisperPrefix(nick);
				local temp_dkp={};
				for i,v in pairs(DKP_table) do temp_dkp[i]=v; end
				table.sort(temp_dkp,
					function(a,b)
						return a.current>b.current
					end
				)
				for i=1,10 do
					v=temp_dkp[i];
				    if v then
						SendChatMessage(DKPT_SV.ChatPrefix..string.format(DKPT_SV.ChatDKP,i,v.nick,v.current),"WHISPER",nil,nick);
					end
				end
				answered=1;
			end
			if isKeyword(DKPT_SV.AANicks,q2) then
				DKPT_DBG(8,nick," wants dkp of ",q3);
				DKPT_WhisperPrefix(nick);
				local temp_dkp={};
				for i,v in pairs(DKP_table) do temp_dkp[i]=v; end
				table.sort(temp_dkp,
					function(a,b)
						return a.current>b.current
					end
				)
				for i,v in pairs(temp_dkp) do
					v=temp_dkp[i];
				    if (type(v)=="table") then
						if (isKeyword(q3,v.nick)) then
							SendChatMessage(DKPT_SV.ChatPrefix..string.format(DKPT_SV.ChatDKP,i,v.nick,v.current),"WHISPER",nil,nick);
						end
					end
				end
				answered=1;
			end
			if isKeyword(DKPT_SV.AAMyClass,q2) then
				DKPT_DBG(8,nick," wants dkp of his/her class...");
				local whonum,charname,class,ii;
--[[				DKPT_DBG(9,"sending who request...","n-\""..nick.."\"");
				SetWhoToUI(1);
				FriendsFrame:UnregisterEvent("WHO_LIST_UPDATE");
				SendWho("n-\""..nick.."\"");
				whonum,_ = GetNumWhoResults();
				FriendsFrame:RegisterEvent("WHO_LIST_UPDATE");
				if(whonum>0) then
				    i=1;
				    while i<=whonum do
				    	charname,_,_,_,class,_,_=GetWhoInfo(i);
				    	DKPT_DBG(9,"who: ",charname,",",class);
				    	if(charname==nick) then
				    		whonum=777;
				    		break;
				    	end
				    	i=i+1;
				    end
				    if(whonum==200) then     ]]--
				    if(RaidClasses[nick]==nil) then
				    	DKPT_DBG(8,"Player is not in raid. Can't get his class.");
				    	SendChatMessage(DKPT_SV.ChatPrefix.."<NOT IMPLEMETNTED YET>","WHISPER",nil,nick);
				    else
				    	class=RaidClasses[nick];
				    	DKPT_DBG(9,"print dkp for class '",class,"'");
						DKPT_WhisperPrefix(nick);
						local temp_dkp={};
						for i,v in pairs(DKP_table) do temp_dkp[i]=v; end
						table.sort(temp_dkp,
							function(a,b)
								return a.current>b.current
							end
						)
						ii=1;
						for i,v in pairs(temp_dkp) do
							v=temp_dkp[i];
						    if (type(v)=="table") then
								if (strlow(v.class)==strlow(class)) then
									SendChatMessage(DKPT_SV.ChatPrefix..string.format(DKPT_SV.ChatDKP,ii,v.nick,v.current),"WHISPER",nil,nick);
									ii=ii+1;
									if ii>DKPT_SV.ChatLines then break; end
								end
							end
						end
					end
--[[				    else
				    	DKPT_DBG(7,"ERROR. Can't find player '"..nick.."' in who results.");
				    end 
				else
					DKPT_DBG(7,"ERROR. Can't get who results.");
				end     ]]--
				answered=1;
			end
			if answered~=1 then
				SendChatMessage(DKPT_SV.ChatPrefix..string.format(DKPT_SV.ChatDKP,ii,v.nick,v.current),"WHISPER",nil,nick);	
			end
			chkFilter(); 
			return 1;
		end
	elseif (event=="CHAT_MSG_WHISPER_INFORM") then
		if not DKPT_ChatFrame then DKPT_ChatFrame=this:GetName(); end
		if DKPT_ChatFrame==this:GetName() then
			DKPT_DBG(9,"whisper to ",nick," : ",text);
		end
		if text then
			local pos;
			pos,_ = string.find(text,DKPT_SV.ChatPrefix,1,true);
			if pos==1 then
				if DKPT_SV.FilterOutAA then return 1; end
			end
		end
	end
	OriginalChatFrame_OnEvent(event);
end

function DKPT_WhisperPrefix(nick)
	if DKPT_SV.PrintTimestamp then
		SendChatMessage(DKPT_SV.ChatPrefix..string.format(DKPT_txt_PrintTNPref,DKP_table_title),"WHISPER",nil,nick);
		SendChatMessage(DKPT_SV.ChatPrefix..string.format(DKPT_txt_PrintTSPref,DKP_tables_timestamp),"WHISPER",nil,nick);
	end
end

function isRank(nick,rank)
	if (not nick) then return false; end
	if (not RaidRanks[nick]) then return false; end
	if (RaidRanks[nick]>=rank) then return true; end
	return false;
end

function DKPT_UnitPopup_OnClick()
	local button = this.value;
	local dropdownFrame = getglobal(UIDROPDOWNMENU_INIT_MENU);
--	local button = UnitPopupMenus[this.owner][index];
	local unit = dropdownFrame.unit;
	local name = dropdownFrame.name;
--	DKPT_DBG(9,"unit popup, index=",index);
	if ( button == "DKPFILTER" ) then
		DKPT_DBG(9,"Add to filter: ",name);
		IS_FILTER=1;
		DKPT_FilterEdit:SetText(DKPT_FilterEdit:GetText().." "..name);
		DKPT_SetFilter(DKPT_FilterEdit:GetText());
		DKPT_FilterCheck:SetChecked(1);
		DKPTScrollFrame_Update();
	else
	    OriginalUnitPopup_OnClick();
	end
end

function DKPT_UpdateMinimapIcon()
	DKPT_MinimapIcon:SetPoint("TOPLEFT","Minimap","TOPLEFT",
		55-((DKPT_SV.MMRadius)*cos(360-DKPT_SV.MMArc)),((DKPT_SV.MMRadius)*sin(360-DKPT_SV.MMArc))-55);
end

function DKPT_OnOptionChanged()
	if(this:GetName()=="DKPT_OptionsFrameChatOptions_ChatPrefix_Editbox") then
		DKPT_SV.ChatPrefix=this:GetText();
	elseif(this:GetName()=="DKPT_OptionsFrameChatOptions_SpentFormat_Editbox") then
		DKPT_SV.SpentFormat=this:GetText();
	elseif(this:GetName()=="DKPT_OptionsFrameChatOptions_CurrentFormat_Editbox") then
		DKPT_SV.CurrentFormat=this:GetText();
	elseif(this:GetName()=="DKPT_OptionsFrameChatOptions_ChatDKP_Editbox") then
		DKPT_SV.ChatDKP=this:GetText();
	elseif(this:GetName()=="DKPT_OptionsFrameChatOptions_ChatDKPspent_Editbox") then
		DKPT_SV.ChatDKPspent=this:GetText();
	elseif(this:GetName()=="DKPT_OptionsFrameChatOptions_ChatLines_Editbox") then
		DKPT_SV.ChatLines=tonumber(this:GetText());
	elseif(this:GetName()=="DKPT_AutoanswerFrame_AAOptions_AAKeywords_Editbox") then
		DKPT_SV.AAKeywords=this:GetText();
	elseif(this:GetName()=="DKPT_AutoanswerFrame_AAOptions_AAMydkp_Editbox") then
		DKPT_SV.AAMydkp=this:GetText();
	elseif(this:GetName()=="DKPT_AutoanswerFrame_AAOptions_AATopten_Editbox") then
		DKPT_SV.AATopten=this:GetText();
	elseif(this:GetName()=="DKPT_AutoanswerFrame_AAOptions_AANicks_Editbox") then
		DKPT_SV.AANicks=this:GetText();
	end
end

function isKeyword(keywords,txt)
	if (keywords==nil) then keywords="" end
	if (txt==nil) then txt="" end
	keywords=" "..string.lower(keywords).." ";
	txt=" "..string.lower(txt).." ";
	return string.find(keywords,txt,1,true);
end

function getFirstKeyword(keywords)
	if (keywords==nil) then keywords="" end
	return string.gsub(keywords,"(%S+)$S*","%1");
end

function dStr(txt)
	if txt==nil then txt=""; end
	if type(txt)~="string" then txt=type(txt); end
	return txt;
end

function dNum(txt)
	if txt==nil then txt=0; end
	if type(txt)=="string" then txt=tonumber(txt); end
	if type(txt)~="number" then txt=0; end
	return txt;
end

function DKPT_DBG (lvl,...)
	if DEBUG>=lvl then
	    local txt="";
	    for i,v in pairs({...}) do
	    	if(type(v)=="nil") then v="[nil]"; end
	    	if(type(v)=="table") then v="[table]"; end
	    	if(type(v)=="boolean") then v=tostring(v); end
	    	txt=txt..v;
	    end
		local txttime=LOG_TIME_COLOR.."["..DKPT_GetTime().."] ";
		DKPT_Log:AddMessage(txttime..LOG_COLORS[lvl]..txt)
		if(DEBUG>9) then
			DEFAULT_CHAT_FRAME:AddMessage("  [DKPT]<"..lvl.."> "..txt,1,1,1,1,1);
		end
	end
end
